package com.toe.common.utils;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.*;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.toe.common.config.AliConfig;
import com.toe.common.pojo.ali.Alipay;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.*;

public class AliPayUtil {

    /**
     * 电脑端支付
     * @param alipay
     * @param httpResponse
     */
    public static void pay(Alipay alipay, HttpServletResponse httpResponse) {
        System.out.println("app_id: "+ AliConfig.APP_ID);
        System.out.println("sign_type: "+ AliConfig.SIGN_TYPE);
        System.out.println("notify_url: "+ AliConfig.NOTIFY_URL);
        //实例化客户端,填入所需参数
        AlipayClient alipayClient = new DefaultAlipayClient(
                 AliConfig.GATEWAY_URL,
                 AliConfig.APP_ID,
                 AliConfig.MERCHANT_PRIVATE_KEY,
                 AliConfig.FORMAT,
                 AliConfig.CHARSET,
                 AliConfig.ALIPAY_PUBLIC_KEY,
                 AliConfig.SIGN_TYPE
        );
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();

        //在公共参数中设置回跳和通知地址
        request.setReturnUrl(alipay.getReturnUrl());
        System.out.println("pay returnUrl -> "+alipay.getReturnUrl());
        String notifyUrl =  AliConfig.NOTIFY_URL+"/"+alipay.getUrl()
                +"/returnUrl/"+alipay.getId();
        System.out.println("url -> "+notifyUrl);
        request.setNotifyUrl(notifyUrl);

        //根据订单编号,查询订单相关信息
//        Order order = IPayService.selectById(orderId);
        //商户订单号，商户网站订单系统中唯一订单号，必填
        String out_trade_no = alipay.getOrderNumber();
        //付款金额，必填
        String total_amount = alipay.getPrice().toString();
        //订单名称，必填
        String subject = alipay.getTitle();
        //商品描述，可空
        String body = alipay.getSpecification();
        System.out.println("订单号: "+out_trade_no);
        System.out.println("付款金额: "+total_amount);
        System.out.println("订单名称: "+subject);
        System.out.println("商品描述: "+body);
        request.setBizContent("{\"out_trade_no\":\"" + out_trade_no + "\","
                + "\"total_amount\":\"" + total_amount + "\","
                + "\"subject\":\"" + subject + "\","
                + "\"body\":\"" + body + "\","
                + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
        String form = "";
        try {
            System.out.println("==========进来了===========");
            form = alipayClient.pageExecute(request).getBody(); // 调用SDK生成表单
            httpResponse.setContentType("text/html;charset=" +  AliConfig.CHARSET);
            httpResponse.getWriter().write(form);// 直接将完整的表单html输出到页面
            httpResponse.getWriter().flush();
            httpResponse.getWriter().close();
        } catch (IOException | AlipayApiException e) { }
    }

    /**
     * 手机端支付
     * @param httpResponse
     */
    public static void phonePay(Alipay alipay, HttpServletResponse httpResponse) {
        AlipayClient alipayClient = new DefaultAlipayClient(
                AliConfig.GATEWAY_URL,
                AliConfig.APP_ID,
                AliConfig.MERCHANT_PRIVATE_KEY,
                AliConfig.FORMAT,
                AliConfig.CHARSET,
                AliConfig.ALIPAY_PUBLIC_KEY,
                AliConfig.SIGN_TYPE); //获得初始化的AlipayClient
        AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();//创建API对应的request
        //在公共参数中设置回跳和通知地址
        request.setReturnUrl(AliConfig.RETURN_URL);
        String notifyUrl = AliConfig.NOTIFY_URL+"/"+alipay.getUrl()
                +"/returnUrl/"+alipay.getId();
        request.setNotifyUrl(notifyUrl);

        String out_trade_no = alipay.getOrderNumber();
        //付款金额，必填
        String total_amount = alipay.getPrice().toString();
        //订单名称，必填
        String subject = alipay.getTitle();
        //商品描述，可空
        String body = alipay.getSpecification();
        request.setBizContent("{" +
                "\"out_trade_no\":\"" + out_trade_no + "\","
                + "\"total_amount\":\"" + total_amount + "\","
                + "\"subject\":\"" + subject + "\","
                + "\"body\":\"" + body + "\","
                + " \"product_code\":\"QUICK_WAP_PAY\"" +
                " }");
        String form = "";
        try {
            form = alipayClient.pageExecute(request).getBody(); //调用SDK生成表单
            httpResponse.setContentType("text/html;charset=" + AliConfig.CHARSET);
            httpResponse.getWriter().write(form);//直接将完整的表单html输出到页面
            httpResponse.getWriter().flush();
            httpResponse.getWriter().close();
        } catch (AlipayApiException | IOException e) { }
    }

    public static void appPay(Alipay alipay, HttpServletResponse httpResponse) {
        AlipayClient alipayClient = new DefaultAlipayClient(
                AliConfig.GATEWAY_URL,
                AliConfig.APP_ID,
                AliConfig.MERCHANT_PRIVATE_KEY,
                AliConfig. FORMAT,
                AliConfig.CHARSET,
                AliConfig.ALIPAY_PUBLIC_KEY,
                AliConfig.SIGN_TYPE
        );
        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();

        String notifyUrl = AliConfig.NOTIFY_URL+"/"+alipay.getUrl()
                +"/returnUrl/"+alipay.getId();
        request.setNotifyUrl(notifyUrl);

        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", alipay.getOrderNumber());

        //付款金额，必填
        String total_amount = alipay.getPrice().toString();
        bizContent.put("total_amount", total_amount);

        bizContent.put("subject", "测试商品");

        bizContent.put("product_code", "QUICK_MSECURITY_PAY");

        request.setBizContent(bizContent.toString());
        AlipayTradeAppPayResponse response = null;

        try {
            response = alipayClient.sdkExecute(request);
        } catch (AlipayApiException e) { }

        if(response.isSuccess()){
            System.out.println("调用成功");
        } else {
            System.out.println("调用失败");
        }
    }

    /**
     * 同步回调
     * @param request
     * @return
     */
    public static String returnUrl(HttpServletRequest request) {
        System.out.println("=================================同步回调=====================================");
        // 获取支付宝GET过来反馈信息
        Map<String, String> params = getAlipayInformation(request);

        System.out.println(params);//查看参数都有哪些
        boolean signVerified = false; // 调用SDK验证签名
        System.out.println("验证成功...");
        try {
            signVerified = AlipaySignature.rsaCheckV1(
                    params,
                    AliConfig.ALIPAY_PUBLIC_KEY,
                    AliConfig.CHARSET,
                    AliConfig.SIGN_TYPE);
        } catch (AlipayApiException e) {

        }
        //验证签名通过
        if(signVerified){
            String out_trade_no = null;
            String trade_no = null;
            String total_amount = null;

            try {
                // 商户订单号
                out_trade_no = new String(request.getParameter("out_trade_no")
                        .getBytes("ISO-8859-1"), "UTF-8");

                // 支付宝交易号
                trade_no = new String(request.getParameter("trade_no")
                        .getBytes("ISO-8859-1"), "UTF-8");

                // 付款金额
                total_amount = new String(request.getParameter("total_amount")
                        .getBytes("ISO-8859-1"), "UTF-8");
            } catch (UnsupportedEncodingException e) {

            }

            System.out.println("商户订单号="+out_trade_no);
            System.out.println("支付宝交易号="+trade_no);
            System.out.println("付款金额="+total_amount);
            System.out.println("付款成功!");
            return "ok";//跳转付款成功页面
        }else{
            return "no";//跳转付款失败页面
        }
    }

    /**
     * 退款
     * @throws IOException
     * @throws AlipayApiException
     */
    public static String refund(Alipay alipay) {
        //获得初始化的AlipayClient
        AlipayClient alipayClient = new DefaultAlipayClient(
                AliConfig.GATEWAY_URL,
                AliConfig.APP_ID,
                AliConfig.MERCHANT_PRIVATE_KEY,
                AliConfig.FORMAT,
                AliConfig.CHARSET,
                AliConfig.ALIPAY_PUBLIC_KEY,
                AliConfig.SIGN_TYPE);
        //设置请求参数
        AlipayTradeRefundRequest alipayRequest =
                new AlipayTradeRefundRequest();

        //商户订单号，必填
        String out_trade_no = alipay.getOrderNumber();
        String trade_no = alipay.getAlipayNumber();
        System.out.println("alipayNumber: "+trade_no);

        //需要退款的金额，该金额不能大于订单金额，必填
        String total_amount = alipay.getPrice().toString();
        System.out.println("money: "+total_amount);

        //标识一次退款请求，同一笔交易多次退款需要保证唯一，如需部分退款，则此参数必传
        String out_request_no = UUID.randomUUID().toString();

        JSONObject bizContent = new JSONObject();
        bizContent.put("trade_no", trade_no);
        bizContent.put("out_trade_no", out_trade_no);
        bizContent.put("refund_amount", total_amount);
        bizContent.put("out_request_no", out_request_no);

        System.out.println("bizContent: "+bizContent.toString());
        alipayRequest.setBizContent(bizContent.toString());

        AlipayTradeRefundResponse response = null;
        try {
            response = alipayClient.execute(alipayRequest);
        } catch (AlipayApiException e) { }

        System.out.println("response: "+response.getCode());
        System.out.println("Msg: "+response.getMsg());

        if(response.isSuccess()){
            return "ok";
        } else {
            return "no";
        }
    }

    /**
     * 获取支付宝GET过来反馈信息
     * @param request
     */
    public static Map<String, String> getAlipayInformation(HttpServletRequest request) {
        Map<String, String> params = new HashMap<>();
        Map<String, String[]> requestParams = request.getParameterMap();
        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = iter.next();
            String[] values = requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            // 乱码解决，这段代码在出现乱码时使用
            try {
                valueStr = new String(valueStr.getBytes("utf-8"), "utf-8");
            } catch (UnsupportedEncodingException e) {

            }
            params.put(name, valueStr);
        }
        return params;
    }

    /**
     * 解析sdk(暂时无用)
     * @param form
     * @return
     */
    private static String parseSDK(String form) {
        String action = form.split("action=\"")[1];
        return action.split("\">\n<input")[0];
    }

}
